/*******************************************************************************
 * Copyright 2011 Alexandre Zglav and Morphiastic
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.morphiastic.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.morphiastic.analysis.analyzers.ElasticAnalyzerType;


@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD })
@Documented
/**
 * Annotation used to flag an Entity Class' property / method as indexable
 */
public @interface ElastiField {

	 
	
	/**
	 * Default value for {@link #indexNullAs} parameter. Indicates that {@code null} values should not be indexed.
	 */
	public static final String DO_NOT_INDEX_NULL = "__DO_NOT_INDEX_NULL__";

	/**
	 * Value for {@link #indexNullAs} parameter indicating that {@code null} values should not indexed using the
	 */
	public static final String DEFAULT_NULL_TOKEN = "__DEFAULT_NULL_TOKEN__";
	
	
	
	/**
	 * @return Returns the field name as it will appear in the index. Defaults to the JavaBean property name.
	 */
	String name() default "";
	
	/**
	 * @return Returns a {@code Store} enum type indicating whether the value should be stored in the document. Defaults to {@code Store.NO}.
	 */
	Store store() default Store.no;

	/**
	 * @return Returns a {@code Index} enum defining whether the value should be indexed or not. Defaults to {@code Index.YES}.
	 */
	Index index() default Index.yes;
	
	/**
	 * @return Returns a {@code Analyze} enum defining whether the value should be analyzed or not. Defaults to {@code Analyze.analyzed}.
	 */
	Analyze analyze() default Analyze.analyzed;
	
	
	/**
	 * @return Returns a {@code TermVector} enum defining if and how term vectors are stored. Defaults to {@code TermVector.NO}.
	 */
	TermVector termVector() default TermVector.no;
	
	/**
	 * @return Returns the analyzer for the field. Defaults to the standard analyzer.
	 * 
	 * This analyzer is both used for indexation and retrieval IF searchAnalyzer is the 
	 * _void searchAnalyzer 
	 * 
	 * OTHERWISE 
	 * 
	 * if the searchAnalyzer was clearly defined to be another analyzer
	 * then analyzer() is used only for indexing and searchAnalyzer is used for searching
	 * 
	 * 
	 */
	Analyzer analyzer() default @Analyzer;
	
	/**
	 * 
	 * @return Returns the analyzer for the field during querying / searching. 
	 * Defaults to the _void analyzer ( which is not an analyzer)
	 * 
	 * if _void is used then the analyzer() is used for both indexing and searching
	 */
	Analyzer searchAnalyzer() default @Analyzer(type = ElasticAnalyzerType._void) ;
	
	
	
	/**
	 * @return Returns the boost factor for the field. Default boost factor is 1.0.
	 */
	Boost boost() default @Boost(value = 1.0F);
	
	
	/**
	 * @return Returns the field bridge used for this field. Default is auto-wired but user can define a field bridge to override the default behaviour.
	 */
	ElastiFieldBridge fieldConverter() default @ElastiFieldBridge;

	/**
	 * @return Returns the value to be used for indexing {@code null}. Per default {@code Field.NO_NULL_INDEXING} is returned indicating that
	 *         null values are not indexed.
	 */
	String indexNullAs() default DO_NOT_INDEX_NULL;
	
	/**
	 * Boolean value if norms should be omitted or not. Defaults to false.
	 * @return
	 */
	boolean omitNorms() default false;
	
	/**
	 * omit_term_freq_and_positions
	 * Boolean value if term freq and positions should be omitted. Defaults to false.
	 * @return
	 */
	boolean omitTermFreqAndPos() default false;
	
	ElastiFieldType elastiFieldType() default ElastiFieldType.auto;
	
	
}
